package com.moshang.exportsql.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.moshang.exportsql.model.MethodExportDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 填充消息的控制器
 */

@RestController
@RequiredArgsConstructor
@Slf4j
public class FIllMethodController {

    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    private static final String PROPERTIES = "properties";
    private static final String ADDITIONAL_PROPERTIES = "additionalProperties";
    private static final String TYPE = "type";
    private static final String ITEMS = "items";
    private static final String ARRAY = "array";
    private static final String OBJECT = "object";
    private static final String DESCRIPTION = "description";
    private static final String REQUIRED = "required";
    private static final String NEW_RESP_BODY = "{\"root\":{\"filedName\":\"root\",\"kid\":\"3f8c799b-fb8f-465b-ba5d-f99cde3fe577\",\"description\":\"根节点\",\"sort\":0,\"type\":\"object\",\"required\":false,\"example\":\"\",\"properties\":{\"msg\":{\"filedName\":\"msg\",\"kid\":\"070e3cd8-df9d-442a-b910-e634cbacb929\",\"description\":\"状态码\",\"sort\":0,\"type\":\"string\",\"required\":false,\"example\":\"\"},\"mfail\":{\"filedName\":\"mfail\",\"kid\":\"01655176-6266-4d83-8087-a70dca22b81e\",\"description\":\"返回信息\",\"sort\":1,\"type\":\"string\",\"required\":false,\"example\":\"\"},\"data\":{\"filedName\":\"data\",\"kid\":\"b4c6a556-6fdd-4f28-bdf9-bdcb9ac01647\",\"description\":\"返回数据\",\"sort\":2,\"type\":\"object\",\"required\":false,\"example\":\"\"},\"errors\":{\"filedName\":\"errors\",\"kid\":\"bee16d33-cb93-4d0d-8664-aadf924aef68\",\"description\":\"错误信息\",\"sort\":3,\"type\":\"string\",\"required\":false,\"example\":\"\"}}}}";

    @GetMapping("/fillMethod")
    public void fillMethod() {
        //查询消息池的所有消息
        List<Map<String, Object>> mlMessageQueryResult = namedParameterJdbcTemplate.queryForList("select * from " +
                        "ml_message",
                new MapSqlParameterSource());
        int batchSize = 100;  // 批处理大小
        int totalRecords = mlMessageQueryResult.size();
        int processedRecords = 0;
        // 准备批量更新的参数
        List<SqlParameterSource> batchUpdateParams = new ArrayList<>();
        for (Map<String, Object> item : mlMessageQueryResult) {
            Long id = (Long) item.get("obj_id"); // 获取 ID

            String requestBody = (String) item.get("req_body");
            String responseBody = (String) item.get("resp_body");
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = null;
            try {
                rootNode = mapper.readTree(requestBody);
                // Call the method to update description
                updateDescription(rootNode, "className", "对象类名");
                updateDescription(rootNode, "thisObj", "当前对象");
                // Print the modified JSON
                String modifiedJsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
                JsonNode respNode = mapper.readTree(responseBody != null && !responseBody.isEmpty() ? responseBody : "{}");
                // 检查是否存在 "data" 字段
                boolean hasDataField = hasField(respNode, "data");

                // 如果不存在 "data" 字段，则插入新的 JSON 对象
                if (!hasDataField) {
                    respNode = mapper.readTree(NEW_RESP_BODY);
                }
                String updatedResponseBody = respNode.toString();

                // 准备参数用于批量更新
                MapSqlParameterSource parameters = new MapSqlParameterSource();
                parameters.addValue("req_body", modifiedJsonString);
                parameters.addValue("resp_body", updatedResponseBody);
                parameters.addValue("obj_id", id);
                batchUpdateParams.add(parameters);
                 // 处理到达批处理大小时，进行批量更新
               if (batchUpdateParams.size() == batchSize) {
                    executeBatchUpdate(batchUpdateParams);
                    processedRecords += batchSize;
                    batchUpdateParams.clear();
                    log.info("Processed {} of {} records.", processedRecords, totalRecords);
                }
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            // 处理剩余的记录
            if (!batchUpdateParams.isEmpty()) {
                executeBatchUpdate(batchUpdateParams);
                processedRecords += batchUpdateParams.size();
                log.info("Processed {} of {} records.", processedRecords, totalRecords);
            }
            log.info("执行成功！");

        }


    }

    private boolean hasField(JsonNode node, String fieldName) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;

            // 检查当前节点
            if (objectNode.has(fieldName)) {
                return true;
            }

            // 递归检查嵌套的属性
            Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                if (hasField(field.getValue(), fieldName)) {
                    return true;
                }
            }
        } else if (node.isArray()) {
            // 检查数组节点
            for (JsonNode arrayItem : node) {
                if (hasField(arrayItem, fieldName)) {
                    return true;
                }
            }
        }
        return false;
    }
    private void executeBatchUpdate(List<SqlParameterSource> batchUpdateParams) {
        String sql = "UPDATE ml_message SET req_body = :req_body, resp_body = :resp_body WHERE obj_id = :obj_id";
        namedParameterJdbcTemplate.batchUpdate(sql, batchUpdateParams.toArray(new SqlParameterSource[0]));
    }

    public static void updateDescription(JsonNode node, String targetFieldName, String newDescription) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;

            // Check and update current node if it matches the targetFieldName
            if (objectNode.has("filedName") && objectNode.get("filedName").asText().equals(targetFieldName)) {
                objectNode.put("description", newDescription);
            }

            // Iterate over all fields in the current object node
            Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                // Recursively check each field
                updateDescription(field.getValue(), targetFieldName, newDescription);
            }
        } else if (node.isArray()) {
            // If the node is an array, iterate over all elements
            for (JsonNode arrayItem : node) {
                updateDescription(arrayItem, targetFieldName, newDescription);
            }
        }
    }
}
